home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Comm / www / tidy_os4.lha / tidy / src / tmbstr.c < prev    next >
C/C++ Source or Header  |  2004-07-25  |  6KB  |  291 lines

  1. /* tmbstr.c -- Tidy string utility functions
  2.  
  3.   (c) 1998-2004 (W3C) MIT, ERCIM, Keio University
  4.   See tidy.h for the copyright notice.
  5.  
  6.   CVS Info :
  7.  
  8.     $Author: hoehrmann $ 
  9.     $Date: 2004/03/13 23:29:22 $ 
  10.     $Revision: 1.9 $ 
  11.  
  12. */
  13.  
  14. #include "tmbstr.h"
  15. #include "lexer.h"
  16.  
  17. /* like strdup but using MemAlloc */
  18. tmbstr tmbstrdup( ctmbstr str )
  19. {
  20.     tmbstr s = NULL;
  21.     if ( str )
  22.     {
  23.         uint len = tmbstrlen( str );
  24.         tmbstr cp = s = (tmbstr) MemAlloc( 1+len );
  25.         while ( 0 != (*cp++ = *str++) )
  26.             /**/;
  27.     }
  28.     return s;
  29. }
  30.  
  31. /* like strndup but using MemAlloc */
  32. tmbstr tmbstrndup( ctmbstr str, uint len )
  33. {
  34.     tmbstr s = NULL;
  35.     if ( str && len > 0 )
  36.     {
  37.         tmbstr cp = s = (tmbstr) MemAlloc( 1+len );
  38.         while ( len-- > 0 &&  (*cp++ = *str++) )
  39.           /**/;
  40.         *cp = 0;
  41.     }
  42.     return s;
  43. }
  44.  
  45. /* exactly same as strncpy */
  46. uint tmbstrncpy( tmbstr s1, ctmbstr s2, uint size )
  47. {
  48.     if ( s1 != NULL && s2 != NULL )
  49.     {
  50.         tmbstr cp = s1;
  51.         while ( *s2 && --size )  /* Predecrement: reserve byte */
  52.             *cp++ = *s2++;       /* for NULL terminator. */
  53.         *cp = 0;
  54.     }
  55.     return size;
  56. }
  57.  
  58. /* Allows expressions like:  cp += tmbstrcpy( cp, "joebob" );
  59. */
  60. uint tmbstrcpy( tmbstr s1, ctmbstr s2 )
  61. {
  62.     uint ncpy = 0;
  63.     while (0 != (*s1++ = *s2++) )
  64.         ++ncpy;
  65.     return ncpy;
  66. }
  67.  
  68. /* Allows expressions like:  cp += tmbstrcat( cp, "joebob" );
  69. */
  70. uint tmbstrcat( tmbstr s1, ctmbstr s2 )
  71. {
  72.     uint ncpy = 0;
  73.     while ( *s1 )
  74.         ++s1;
  75.  
  76.     while (0 != (*s1++ = *s2++) )
  77.         ++ncpy;
  78.     return ncpy;
  79. }
  80.  
  81. /* exactly same as strcmp */
  82. int tmbstrcmp( ctmbstr s1, ctmbstr s2 )
  83. {
  84.     int c;
  85.     while ((c = *s1) == *s2)
  86.     {
  87.         if (c == '\0')
  88.             return 0;
  89.  
  90.         ++s1;
  91.         ++s2;
  92.     }
  93.  
  94.     return (*s1 > *s2 ? 1 : -1);
  95. }
  96.  
  97. /* returns byte count, not char count */
  98. uint tmbstrlen( ctmbstr str )
  99. {
  100.     uint len = 0;
  101.     if ( str ) 
  102.     {
  103.         while ( *str++ )
  104.             ++len;
  105.     }
  106.     return len;
  107. }
  108.  
  109. /*
  110.  MS C 4.2 doesn't include strcasecmp.
  111.  Note that tolower and toupper won't
  112.  work on chars > 127.
  113.  
  114.  Neither does ToLower()!
  115. */
  116. int tmbstrcasecmp( ctmbstr s1, ctmbstr s2 )
  117. {
  118.     uint c;
  119.  
  120.     while (c = (uint)(*s1), ToLower(c) == ToLower((uint)(*s2)))
  121.     {
  122.         if (c == '\0')
  123.             return 0;
  124.  
  125.         ++s1;
  126.         ++s2;
  127.     }
  128.  
  129.     return (*s1 > *s2 ? 1 : -1);
  130. }
  131.  
  132. int tmbstrncmp( ctmbstr s1, ctmbstr s2, uint n )
  133. {
  134.     uint c;
  135.  
  136.     while ((c = (byte)*s1) == (byte)*s2)
  137.     {
  138.         if (c == '\0')
  139.             return 0;
  140.  
  141.         if (n == 0)
  142.             return 0;
  143.  
  144.         ++s1;
  145.         ++s2;
  146.         --n;
  147.     }
  148.  
  149.     if (n == 0)
  150.         return 0;
  151.  
  152.     return (*s1 > *s2 ? 1 : -1);
  153. }
  154.  
  155. int tmbstrncasecmp( ctmbstr s1, ctmbstr s2, uint n )
  156. {
  157.     uint c;
  158.  
  159.     while ( (c = tolower(*s1)) == (uint) tolower(*s2) )
  160.     {
  161.         if (c == '\0')
  162.             return 0;
  163.  
  164.         if (n == 0)
  165.             return 0;
  166.  
  167.         ++s1;
  168.         ++s2;
  169.         --n;
  170.     }
  171.  
  172.     if (n == 0)
  173.         return 0;
  174.  
  175.     return (*s1 > *s2 ? 1 : -1);
  176. }
  177.  
  178. /* return offset of cc from beginning of s1,
  179. ** -1 if not found.
  180. */
  181. int tmbstrnchr( ctmbstr s1, uint maxlen, tmbchar cc )
  182. {
  183.     int i;
  184.     ctmbstr cp = s1;
  185.  
  186.     for ( i = 0; (uint)i < maxlen; ++i, ++cp )
  187.     {
  188.         if ( *cp == cc )
  189.             return i;
  190.     }
  191.  
  192.     return -1;
  193. }
  194.  
  195. ctmbstr tmbsubstrn( ctmbstr s1, uint len1, ctmbstr s2 )
  196. {
  197.     uint len2 = tmbstrlen(s2);
  198.     int ix, diff = len1 - len2;
  199.  
  200.     for ( ix = 0; ix <= diff; ++ix )
  201.     {
  202.         if ( tmbstrncmp(s1+ix, s2, len2) == 0 )
  203.             return (ctmbstr) s1+ix;
  204.     }
  205.     return NULL;
  206. }
  207.  
  208. ctmbstr tmbsubstrncase( ctmbstr s1, uint len1, ctmbstr s2 )
  209. {
  210.     uint len2 = tmbstrlen(s2);
  211.     int ix, diff = len1 - len2;
  212.  
  213.     for ( ix = 0; ix <= diff; ++ix )
  214.     {
  215.         if ( tmbstrncasecmp(s1+ix, s2, len2) == 0 )
  216.             return (ctmbstr) s1+ix;
  217.     }
  218.     return NULL;
  219. }
  220.  
  221. ctmbstr tmbsubstr( ctmbstr s1, ctmbstr s2 )
  222. {
  223.     uint len1 = tmbstrlen(s1), len2 = tmbstrlen(s2);
  224.     int ix, diff = len1 - len2;
  225.  
  226.     for ( ix = 0; ix <= diff; ++ix )
  227.     {
  228.         if ( tmbstrncasecmp(s1+ix, s2, len2) == 0 )
  229.             return (ctmbstr) s1+ix;
  230.     }
  231.     return NULL;
  232. }
  233.  
  234. /* Transform ASCII chars in string to lower case */
  235. tmbstr tmbstrtolower( tmbstr s )
  236. {
  237.     tmbstr cp;
  238.     for ( cp=s; *cp; ++cp )
  239.         *cp = (tmbchar) ToLower( *cp );
  240.     return s;
  241. }
  242.  
  243. /* Transform ASCII chars in string to upper case */
  244. tmbstr tmbstrtoupper(tmbstr s)
  245. {
  246.     tmbstr cp;
  247.  
  248.     for (cp = s; *cp; ++cp)
  249.         *cp = (tmbchar)ToUpper(*cp);
  250.  
  251.     return s;
  252. }
  253.  
  254. Bool tmbsamefile( ctmbstr filename1, ctmbstr filename2 )
  255. {
  256. #if FILENAMES_CASE_SENSITIVE
  257.     return ( tmbstrcmp( filename1, filename2 ) == 0 );
  258. #else
  259.     return ( tmbstrcasecmp( filename1, filename2 ) == 0 );
  260. #endif
  261. }
  262.  
  263. int tmbvsnprintf(tmbstr buffer, size_t count, ctmbstr format, va_list args)
  264. {
  265.     int retval;
  266. #if HAS_VSNPRINTF
  267.     retval = vsnprintf(buffer, count - 1, format, args);
  268.     /* todo: conditionally null-terminate the string? */
  269.     buffer[count - 1] = 0;
  270. #else
  271.     retval = vsprintf(buffer, format, args);
  272. #endif /* HAS_VSNPRINTF */
  273.     return retval;
  274. }
  275.  
  276. int tmbsnprintf(tmbstr buffer, size_t count, ctmbstr format, ...)
  277. {
  278.     int retval;
  279.     va_list args;
  280.     va_start(args, format);
  281. #if HAS_VSNPRINTF
  282.     retval = vsnprintf(buffer, count - 1, format, args);
  283.     /* todo: conditionally null-terminate the string? */
  284.     buffer[count - 1] = 0;
  285. #else
  286.     retval = vsprintf(buffer, format, args);
  287. #endif /* HAS_VSNPRINTF */
  288.     va_end(args);
  289.     return retval;
  290. }
  291.